function [trimmedX,ZCR_Vector,Erg_Vector] = myVAD(x)

%Date:          01/09/08

%Syntax:        trimmedSample = myVAD2(samplex);

%Esta funciona acepta una muestra de sonido como entrada y devuelve una versión
%recortada con las secciones de 'silencio' eliminadas. Se conoce como detección 
%de actividad de voz (VAD: Voice Activity Detection). Utiliza el algoritmo de 
%Rabiner & Sambur (1975). 

%Parametros >> constantes temproales fijas

Ini         = 0.1;           %Duración inicial de silencio en segundos
Ts          = 0.01;          %Ancho del frame en segundos
Tsh         = 0.005;         %Corrimiento del frame en segundos. overlap 50%
Fs          = 16000;         %Frecuencia de Muestreo
counter1    = 0;   
counter2    = 0;
counter3    = 0;
counter4    = 0;
ZCRCountf   = 0;            %Guarda cuenta progresiva de la tasa de cruces > IZCT
ZCRCountb   = 0;            %igual que arriba pero regresiva
ZTh         = 40;           %ZCR de comparación para umbral
w_sam       = fix(Ts*Fs);                   %No  muestras/ventana 
o_sam       = fix(Tsh*Fs);                  %No  muestras/solapamiento
lengthX     = length(x);
segs        = fix((lengthX-w_sam)/o_sam)+1;  %Número de segmentos en la señal de voz
sil         = fix((Ini-Ts)/Tsh)+1;           %No de segmentos en un periodo de silencio
win         = hamming(w_sam);
Limit       = o_sam*(segs-1)+1;             %índice de comienzo del último segmento
FrmIndex    = 1:o_sam:Limit;                %Vector que contiene índice de comienzo 
                                            %para cada segmento
ZCR_Vector  = zeros(1,segs);                %Vector para reservar ZCR
                                            %para todos los segmentos
                                     
%Las siguientes líneas calculan y devuelven ZCR para todos los segmentos en la
%muestra de voz  

% No considera como cruce cuando cero si x(t)=0
x           = x / max(abs(x));     %normalizacion

for t = 1:segs
        ZCRCounter = 0; 
        nextIndex  = (t-1)*o_sam+1;
        
        for r = nextIndex+1:(nextIndex+w_sam-1)
            
            if (x(r) > 0) && (x(r-1) > 0)
            elseif (x(r) > 0) && (x(r-1) < 0)
                ZCRCounter = ZCRCounter + 1;
            elseif (x(r) < 0) && (x(r-1) < 0)
         
            elseif (x(r) < 0) && (x(r-1) > 0)
                ZCRCounter = ZCRCounter + 1;
            end
            
        end
        
        ZCR_Vector(t) = ZCRCounter;
end

% subplot (2,2,2); 
%                 plot(ZCR_Vector,'LineWidth',2);
%                 xlim([0 359]);
%                 ylabel('Cruces por Cero');
%                 xlabel('Numero de frames(segmentos)');
%                 title('ZCR');


%El código a continuación calcula y devuelve la energía del frame para todos los
%segmentos en la muestra de voz

Erg_Vector = zeros(1,segs);         %Vector de energia

for u = 1:segs
        nextIndex       = (u-1)*o_sam+1;
        Energy          = x(nextIndex:nextIndex+w_sam-1).*win;
        Erg_Vector(u)   = sum(abs(Energy));
end

% subplot(2,2,3);
%                 plot(Erg_Vector,'LineWidth',2,'Color',[1,0,0]);
%                 xlim([0 359]);
%                 ylabel('Amplitud');
%                 xlabel('Numero de segmentos');
%                 title('Energia de cada segmento');
%                 

IMN     = mean(Erg_Vector(1:sil));  %Media: Energía del silencio (energía de ruido)
IMX     = max(Erg_Vector);          %Valor maximo de energia dentro de la palabra.
I1      = 0.05 * (IMX-IMN) + IMN;   %I1 & I2 son los umbrales iniciales
I2      = 4 * IMN;
ITL     = max(I1,I2);               %umbral de energia inferior
ITU     = 5 * min(I1,I2);                  %umbral de energia superior
IZC     = mean(ZCR_Vector(1:sil));  %ZCR promedio para la region de silencio
stdev   = std(ZCR_Vector(1:sil));   %desviacion estandar para ZCR de la region de silencio
IZCT    = min(ZTh,IZC+2*stdev);     %Umbral ZCR
indexi  = zeros(1,lengthX);         %se crean 4 vectores fila
indexj  = indexi;                   %aqui para facilitar algunos calculos mas abajo
indexk  = indexi;
indexl  = indexi;


% dlmwrite('Indices.txt',IMN,'-append','delimiter','\t','roffset',1);
% dlmwrite('Indices.txt',IMX,'-append','delimiter','\t');
% dlmwrite('Indices.txt',I1,'-append','delimiter','\t');
% dlmwrite('Indices.txt',I2,'-append','delimiter','\t');
% dlmwrite('Indices.txt',ITL,'-append','delimiter','\t');
% dlmwrite('Indices.txt',ITU,'-append','delimiter','\t');


%Buscar por frame con energia mayor que ITU

for i = 1:length(Erg_Vector)
    if (Erg_Vector(i) > ITU)
        counter1 = counter1 + 1;
        indexi(counter1) = i;
    end
end

ITUs = indexi(1);

%Buscar por frame con energia menor?? que ITL

for j = ITUs:-1:1
    if (Erg_Vector(j) > ITL)
        counter2 = counter2 + 1;
        indexj(counter2) = j;
    end
end

start = indexj(1)+1;
Erg_Vectorf = fliplr(Erg_Vector);

%da vuelta el vector de energia

%Buscar hacia adelante por frame con energia mayor que ITU

for k = 1:length(Erg_Vectorf)
    if (Erg_Vectorf(k) > ITU)
        counter3 = counter3 + 1;
        indexk(counter3) = k;
    end
end
ITUf = indexk(1);

%Buscar mas adelante por frame con energia mas alta que ITL

for l = ITUf:-1:1
    if (Erg_Vectorf(l) > ITL)
        counter4 = counter4 + 1;
        indexl(counter4) = l;
    end
end

finish = length(Erg_Vector)-indexl(1)+1;%Tentative finish index
    
%Buscar en sentido inverso desde el indice de comienzo, por zcr mayores que IZCT
   
BackSearch = min(start,25);
for m = start:-1:start-BackSearch+1
        rate = ZCR_Vector(m);
        if rate > IZCT
            ZCRCountb = ZCRCountb + 1;
            realstart = m;
        end
end

if ZCRCountb > 7 %3
    start = realstart;          %Si IZCT es sobrepasado en mas de 3 frames
                                %poner inicio en el ultimo indice donde
                                %IZCT fue sobrepasado
end

%Buscar hacia adelante desde el indice de final por zcr mas altas que IZCT

FwdSearch = min(length(Erg_Vector)-finish,25);

for n = finish+1:finish+FwdSearch
        rate = ZCR_Vector(n);
        if rate > IZCT
            ZCRCountf = ZCRCountf + 1;
            realfinish = n;
        end
end
if ZCRCountf > 7 %3
    finish = realfinish;        %Si IZCT es sobrepasado en mas de than X frames
                                %setear final al ultimo indice donde IZCT
                                %es sobrepasado.
end

x_start     = FrmIndex(start);      %actual sample index for frame 'start'
x_finish    = FrmIndex(finish-1);   %actual sample index for frame 'finish'
trimmedX    = x(x_start:x_finish);  %Trim speech sample by start and finish %indices



                
              









